#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "MCE.h"


//================================================================================================================================
// Routine to sort out the Recording tag array (remove empty entries and recalculate depth
//================================================================================================================================
void shuffle_recordings()
{ int i,j,k,kf,kt,kl,foundoneempty;
  char str[80];

//  Tlog("Shuffle Recordings","entered");
  foundoneempty=1;
  while (foundoneempty)
    { foundoneempty=0;
//      Tlog("Shuffle Recordings","while loop");
      for (i=1; i<(geti(TAG_RecordingDepth)+1); i++)
        { j=(i*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
          if ( (geti(TAG_RecordingStatus1+j)==0) && (i<MAX_RECORDING_DEPTH) )
            { // Found an empty slot - shuffle the remainder up
              foundoneempty=1;
//              sprintf(str,"at %d sz %d",i,j);
//              Tlog("Found an empty entry",str);
              for (k=i; k<(MAX_RECORDING_DEPTH); k++)
                { // Shuffle up from k+1 to k
                  kf=((k+1)*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
                  kt=(k*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
//                  sprintf(str,"from %d (sz %d) to %d (sz %d)",k+1,kf,k,kt);
//                  Tlog("Copying",str);
                  puti(TAG_RecordingStatus1+kt,geti(TAG_RecordingStatus1+kf));
                  puti(TAG_RecordingSession1+kt,geti(TAG_RecordingSession1+kf));
                  puti(TAG_RecordingTrackNumber1+kt,geti(TAG_RecordingTrackNumber1+kf));
                  putst(TAG_RecordingMediaName1+kt,getst(TAG_RecordingMediaName1+kf));
                  putst(TAG_RecordingChannelName1+kt,getst(TAG_RecordingChannelName1+kf));
                  // Now zero the last entry
                  kl=(MAX_RECORDING_DEPTH*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
                  puti(TAG_RecordingStatus1+kl,0);
                  puti(TAG_RecordingSession1+kl,0);
                  puti(TAG_RecordingTrackNumber1+kl,0);
                  putst(TAG_RecordingMediaName1+kl,"Emptied");
                  putst(TAG_RecordingChannelName1+kl,"Emptied");

//                  sprintf(str,"%d",geti(TAG_RecordingStatus1+kt)); Tlog("To Status",str);
//                  sprintf(str,"%d",geti(TAG_RecordingSession1+kt)); Tlog("To Session",str);
//                  sprintf(str,"%d",geti(TAG_RecordingTrackNumber1+kt)); Tlog("To TrackNumber",str);
//                  Tlog("To MediaName",getst(TAG_RecordingMediaName1+kt));
//                  Tlog("To ChannelName",getst(TAG_RecordingChannelName1+kt));
                }
              // And reduce the depth
              puti(TAG_RecordingDepth,(geti(TAG_RecordingDepth)-1));                      // and reduce depth
//              sprintf(str,"=%d",geti(TAG_RecordingDepth));
//              Tlog("Depth",str);
              break;
            }
        }
    }
  // Now do a check that depth is correct
  k=0;
  for (i=1; i<(MAX_RECORDING_DEPTH+1); i++)
    { j=(i*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
      if (geti(TAG_RecordingStatus1+j)!=0) k=i;
    }
  if (geti(TAG_RecordingDepth)!=k) 
    { sprintf(str,"depth=%d check=%d",geti(TAG_RecordingDepth),k);
      Tlog("Recording shuffle failed",str);
    }
}


//================================================================================================================================
// Routine to process the recording messages
//================================================================================================================================
extern void  __stdcall MCE_update_recording_status(int tag,int wasi,char *wass, char *line)
{  int i,j,depth,depthsz,found;
   char str[256];

   depth=geti(TAG_RecordingDepth);
   if (depth>MAX_RECORDING_DEPTH) 
     { Tlog("recording status","too deep"); 
       depth=MAX_RECORDING_DEPTH; 
       puti(TAG_RecordingDepth,depth);
     } /**/
   depthsz=(depth*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
   sprintf(str,"depth=%d depthsz=%d tag=%d wasi=%d wass=%s line=%s",depth,depthsz,tag,wasi,wass,line);
   Tlog("recording status entered",str);

   switch (tag)
      { // If we get a recording=true assume it's at the next level down
        case TAG_Recording:
            if (geti(TAG_Recording)==1)                           // if this is a Recording=True  
              { if (depth<MAX_RECORDING_DEPTH)
                  { puti(TAG_RecordingDepth,(geti(TAG_RecordingDepth)+1)); // Increase depth
                    depth=geti(TAG_RecordingDepth);
                    depthsz=(depth*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
                    sprintf(str,"depth=%d depthsz=%d",depth,depthsz);
                    Tlog("rs recording=1",str);
                    puti(TAG_RecordingStatus1+depthsz,2);
                    puti(TAG_RecordingSession1+depthsz,geti(TAG_StartSession));
                    puti(TAG_StartSession,geti(TAG_PreviousStatusFlag));
                    puti(TAG_SessionFlag,geti(TAG_PreviousStatusFlag));
                  }
              }
            else   { puti(TAG_RecordingStatus1+depthsz,0);                       // its a recording=false
                     puti(TAG_RecordingSession1+depthsz,0);                      // so zero out everything at this depth
                     puti(TAG_RecordingTrackNumber1+depthsz,0);
                     putst(TAG_RecordingMediaName1+depthsz,"Finished");
                     putst(TAG_RecordingChannelName1+depthsz,"Done");
                     puti(TAG_RecordingDepth,geti(TAG_RecordingDepth)-1); // and reduce depth
                   }
          
          break;

        case TAG_MediaName:
          if (depth>0)
            { if (geti(TAG_RecordingStatus1+depthsz)==2)
                {  puti(TAG_RecordingStatus1+depthsz,3);
                   putst(TAG_RecordingMediaName1+depthsz,getst(TAG_MediaName));
                   putst(TAG_MediaName,wass);                                      // set the media name back
                }
            }
          else if ( (geti(TAG_Status)==TAG_FS_Radio) || (geti(TAG_Recording)==0) )
            { if (!strcmp(getst(TAG_RadioChannelTag),gettag(TAG_MediaName)))
                  putst(TAG_RadioChannel,MCE_dll_get_radiochannel(&line[getlength(tag)+1])); 
            }
          break;
        case TAG_TrackNumber:    // Check if Tracknumber and we are in TV mode - if so set the TV Channel Name
          if ((depth>0) && (geti(TAG_RecordingStatus1+depthsz)==3) )
            { puti(TAG_RecordingStatus1+depthsz,4);
              puti(TAG_RecordingTrackNumber1+depthsz,geti(TAG_TrackNumber)); // store the recording channel
              putst(TAG_RecordingChannelName1+depthsz,MCE_dll_get_tvchannel(&line[getlength(tag)+1]));
              puti(TAG_TrackNumber,wasi);                                    // set the channel back
              putst(TAG_TrackNumber,wass);
              putst(TAG_ChannelName,MCE_dll_get_tvchannel(wass));
            }
          else // if ( (geti(TAG_Status)==TAG_FS_TV) || (geti(TAG_Recording)==0) )
            { putst(TAG_ChannelName,MCE_dll_get_tvchannel(&line[getlength(tag)+1])); }
          break;
        case TAG_EndSession:
          if (depth>0)
            { // Find this session in the list and end it (may involve shuffling!)
//              Tlog("Recording update","looking to end session");
              found=0;
              for (i=0; i<MAX_RECORDING_DEPTH; i++)
                { j=i*RECORDING_TAGS_SIZE;
                  sprintf(str,"i=%d j=%d Endsession=%d Recording session=%d",i+1,j,
                                                       geti(TAG_EndSession),geti(TAG_RecordingSession1+j));
                  Tlog("checking session",str);
                  if (geti(TAG_EndSession)==geti(TAG_RecordingSession1+j))
                    { // End this session
                      sprintf(str,"Session %d",geti(TAG_RecordingSession1+j));
                      Tlog("Recording Completed -",str);
                      puti(TAG_RecordingStatus1+j,0);
                      puti(TAG_RecordingSession1+j,0);
                      puti(TAG_RecordingTrackNumber1+j,0);
                      putst(TAG_RecordingMediaName1+j,"Session Finished");
                      putst(TAG_RecordingChannelName1+j,"Session Done"); 
                      // Now we need to shuffle the sessions to remove gaps
                      shuffle_recordings();
//                      sprintf(str,"depth=%d",geti(TAG_RecordingDepth));
//                      Tlog("Shuffled",str);
                      found=1;
                      break;               // need to exit the loop since we messed up the array!
                    }
                  }
              if (found==0) { if (geti(TAG_Initialising)==0) set_mode(TAG_Stop,0,1,0,0,0,0,0,0,0,0,0,0); } // Stop implied

//              Tlog("Session","Checked");
              // and set recording off if there are no more recording sessions
              if (geti(TAG_RecordingDepth)==0) putbi(TAG_Recording,0); 
            }
          else { if (geti(TAG_Initialising)==0) set_mode(TAG_Stop,0,1,0,0,0,0,0,0,0,0,0,0); } // Stop implied
          break;
      }
   //
   // Amalgamate the results for display
   // Copy the first one
   //
   depthsz=(geti(TAG_RecordingDepth)*RECORDING_TAGS_SIZE)-RECORDING_TAGS_SIZE;
   if (depthsz<0) depthsz=0;
   puti(TAG_RecordingStatus,geti(TAG_RecordingStatus1+depthsz));
   puti(TAG_RecordingSession,geti(TAG_RecordingSession1+depthsz));
   puti(TAG_RecordingTrackNumber,geti(TAG_RecordingTrackNumber1+depthsz));
   putst(TAG_RecordingMediaName,getst(TAG_RecordingMediaName1+depthsz));
   putst(TAG_RecordingChannelName,getst(TAG_RecordingChannelName1+depthsz));


}
 
